﻿using System;
using System.Data;
using System.Collections;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Utilities;

namespace Version3.SharePoint
{
 

    [CLSCompliant(false)]
    [Guid("096AFD2B-A00E-4000-89AB-72B1C6AD1775")]
    public class ContentLookupFieldControl : BaseFieldControl
    {

        #region static assist
        private static string JS_TEMPLATE = GetEmbededJSTemplate();
        private static string DIALOG_VALS = GetDialogStringFromAssembly();
        const int DISPLAY_TEXT_TRIM_LENGTH = 75;

        private static string GetDialogStringFromAssembly()
        {
            System.Reflection.Assembly thisAssembly = System.Reflection.Assembly.GetExecutingAssembly();
            return typeof(Version3.SharePoint.ContentLookupFieldPickerDialog).ToString() + "," + thisAssembly.FullName;
        }

        private static string GetEmbededJSTemplate()
        {
            string returnValue = string.Empty;
            System.Reflection.Assembly thisAssembly = System.Reflection.Assembly.GetExecutingAssembly();
            using (System.IO.StreamReader fileStream = new System.IO.StreamReader(thisAssembly.GetManifestResourceStream("Version3.SharePoint.CallBackScriptTemplate.js")))
            {
                returnValue =  fileStream.ReadToEnd();
            }
            return returnValue.Replace("%DISPLAYTRIMLENGTH%", DISPLAY_TEXT_TRIM_LENGTH.ToString());
        }
        #endregion
         
        #region Declarations
        private ContentLookupField _ParentField;
        protected ListBox _ContentLookupListBox;
        protected HtmlInputHidden _HiddenFieldValue;
        protected Image _CLLookupButton;
        protected Image _ClDeleteButton;
        protected Image _ClDeleteAllButton;
        private string _JSLink = Guid.NewGuid().ToString().ToUpper().Replace("-", string.Empty);
        bool _ParentIsConfigured = true;
        #endregion

        #region Constructor
        public ContentLookupFieldControl(ContentLookupField parentField)
        {
            _ParentField = parentField;
            if (string.IsNullOrEmpty(_ParentField.WebURL)) _ParentIsConfigured = false;
            if (string.IsNullOrEmpty(_ParentField.ListName)) _ParentIsConfigured = false;
            if (string.IsNullOrEmpty(_ParentField.FieldOne)) _ParentIsConfigured = false;
            if (string.IsNullOrEmpty(_ParentField.FieldTwo)) _ParentIsConfigured = false;
        }
        #endregion

        #region Control implementation
        protected override string DefaultTemplateName
        {
            get
            {
                return "ContentLookupFieldControl";
            }
        }

        protected override string DefaultAlternateTemplateName
        {
            get
            {
                return string.Empty;
            }
        }

        public override void Focus()
        {
            EnsureChildControls();
            base.Focus();
        }

        protected override void CreateChildControls()
        {
            if (null != this.Field)
            {
                base.CreateChildControls();

                _ContentLookupListBox = (ListBox)TemplateContainer.FindControl("ContentLookupListBox");
                _HiddenFieldValue = (HtmlInputHidden)TemplateContainer.FindControl("ContentLookupListBoxData");
                _CLLookupButton = (Image)TemplateContainer.FindControl("CLLookupButton");
                _ClDeleteButton = (Image)TemplateContainer.FindControl("ClDeleteButton");
                _ClDeleteAllButton = (Image)TemplateContainer.FindControl("ClDeleteAllButton");

                if (_ParentIsConfigured)
                {
                    if (SPControlMode.Edit == this.ControlMode || SPControlMode.New == this.ControlMode)
                    {
                        //Wire up the event handlers
                        _CLLookupButton.Style.Add("cursor", "hand");
                        _CLLookupButton.Attributes.Add("onclick", "ContentLookupList_Dialog" + _JSLink + "();return false;");
                        _CLLookupButton.ToolTip = "Lookup new value";

                        _ClDeleteAllButton.Style.Add("cursor", "hand");
                        _ClDeleteAllButton.Attributes.Add("onclick", "ContentLookupList_Clear" + _JSLink + "();return false;");
                        _ClDeleteAllButton.ToolTip = "Delete all";

                        _ClDeleteButton.Style.Add("cursor", "hand");
                        _ClDeleteButton.Attributes.Add("onclick", "ContentLookupList_Delete" + _JSLink + "();return false;");
                        _ClDeleteButton.ToolTip = "Delete hightlighted item";
                    }
                }
            }
        }

        protected override void Render(HtmlTextWriter output)
        {
            EnsureChildControls();
            base.Render(output);
            if (_ParentIsConfigured)
            {
                //RegisterClientScriptBlock does not seem to work here, so we will just
                //write it out to the client 
                output.Write(PickerJavaScript());
            }
        }
        #endregion

        #region Tag expansion

        private string PickerJavaScript()
        {
            if (!_ParentIsConfigured || (null == _ContentLookupListBox) || (null == _HiddenFieldValue))
            {
                return string.Empty;
            }

            System.Text.StringBuilder dialogUrl = new System.Text.StringBuilder();
            dialogUrl.Append("/_layouts/picker.aspx?MultiSelect=");
            dialogUrl.Append(SPHttpUtility.UrlKeyValueEncode("True"));
            string customProperty =  _ParentField.WebURL + ";" + _ParentField.ListName + ";" + _ParentField.FieldOne + ";" + _ParentField.FieldTwo + ";" + _ParentField.FieldThree;
            dialogUrl.Append("&CustomProperty=" + SPHttpUtility.UrlKeyValueEncode(customProperty));
            dialogUrl.Append("&EntitySeparator=" + SPHttpUtility.UrlKeyValueEncode(";"));
            dialogUrl.Append("&DialogTitle=" + SPHttpUtility.UrlKeyValueEncode("Select Curriculum Link"));
            dialogUrl.Append("&DialogImage=" + SPHttpUtility.UrlKeyValueEncode("/_layouts/images/link.gif"));
            dialogUrl.Append("&PickerDialogType=" + SPHttpUtility.UrlKeyValueEncode(DIALOG_VALS));

            string returnValue = JS_TEMPLATE.Replace("%JSLINK%", _JSLink);
            returnValue = returnValue.Replace("%LISTBOX%", _ContentLookupListBox.ClientID);
            returnValue = returnValue.Replace("%LISTBOXDATA%", _HiddenFieldValue.ClientID);
            returnValue = returnValue.Replace("%DIALOGURL%", dialogUrl.ToString());

            return returnValue;

        }
  



        private string ExpandRow(string keyValue, SPList searchList, bool verboseText)
        {
            string returnValue = string.Empty;
            try
            {
                SPListItemCollection searchItems = null;
                SPQuery searchQuery = new SPQuery();

                if (!string.IsNullOrEmpty(_ParentField.FieldOne)) searchQuery.ViewFields += string.Format("<FieldRef Name=\"{0}\" />", _ParentField.FieldOne);
                if (!string.IsNullOrEmpty(_ParentField.FieldTwo)) searchQuery.ViewFields += string.Format("<FieldRef Name=\"{0}\" />", _ParentField.FieldTwo);
                if (!string.IsNullOrEmpty(_ParentField.FieldThree)) searchQuery.ViewFields += string.Format("<FieldRef Name=\"{0}\" />", _ParentField.FieldThree);

                searchQuery.Query = string.Format("<Where><Eq><FieldRef Name='{0}' Nullable=\"TRUE\"/><Value Type=\"Text\">{1}</Value></Eq></Where>", _ParentField.FieldOne, keyValue);
                searchItems = searchList.GetItems(searchQuery);
                if (null != searchItems)
                {
                    if (searchItems.Count > 0)
                    {
                        SPListItem expansionItem = searchItems[0];
                        if (!string.IsNullOrEmpty(_ParentField.FieldOne))
                        {
                            if (verboseText)
                            {
                                returnValue += expansionItem[_ParentField.FieldOne].ToString() + " ";
                            }
                            else
                            {
                                returnValue = expansionItem[_ParentField.FieldOne].ToString() + "=";
                            }
                        }
                        if (!string.IsNullOrEmpty(_ParentField.FieldTwo))
                        {
                            returnValue += expansionItem[_ParentField.FieldTwo].ToString() + " ";
                        }
                        if (verboseText && (!string.IsNullOrEmpty(_ParentField.FieldThree)))
                        {
                            returnValue += expansionItem[_ParentField.FieldThree].ToString() + " ";
                        }
                    }
                }
            }
            catch { }
            return returnValue;
        }
        #endregion

        #region Value
        public override object Value
        {
            get
            {
                EnsureChildControls();
                SPFieldMultiChoiceValue returnValue = new SPFieldMultiChoiceValue();
                string metaData = string.Empty;
                using (SPSite topSite = new SPSite(_ParentField.WebURL))
                {
                    using (SPWeb topWeb = topSite.OpenWeb())
                    {
                        SPList searchList = topWeb.Lists[_ParentField.ListName];
                        if (Page.IsPostBack)
                        {
                            string rawData = _HiddenFieldValue.Value;
                            string[] newValues = rawData.Split('~');
                            foreach (string newValue in newValues)
                            {
                                returnValue.Add(newValue);
                                metaData += ExpandRow(newValue, searchList,true);
                            }
                        }
                        else
                        {
                            foreach (ListItem listItem in _ContentLookupListBox.Items)
                            {
                                returnValue.Add(listItem.Text);
                                metaData += ExpandRow(listItem.Text, searchList,true);
                            }
                        }
                    }
                }
                if (!string.IsNullOrEmpty(_ParentField.RelatedField))
                {
                    try
                    {
                        this.ListItem[_ParentField.RelatedField] = metaData;
                    }
                    catch (Exception missingFieldError)
                    {
                        //Ok to ignore if the user removed the tag field
                        System.Diagnostics.Trace.WriteLine(missingFieldError.Message);
                    }
                }
                return returnValue;
            }

            set
            {
                if (_ParentIsConfigured)
                {
                    EnsureChildControls();
                    _ContentLookupListBox.Items.Clear();
                    _HiddenFieldValue.Value = string.Empty;
                    SPFieldMultiChoiceValue fieldValue = null;
                    if (value is string)
                    {
                        fieldValue = new SPFieldMultiChoiceValue((string)value);
                    }
                    else
                    {
                        if (value is SPFieldMultiChoiceValue)
                        {
                            fieldValue = (SPFieldMultiChoiceValue)value;
                        }
                    }
                    if (null != fieldValue)
                    {
                        using (SPSite topSite = new SPSite(_ParentField.WebURL))
                        {
                            using (SPWeb topWeb = topSite.OpenWeb())
                            {
                                SPList searchList = topWeb.Lists[_ParentField.ListName];
                                for (int dataIndex = 0; dataIndex < fieldValue.Count; dataIndex++)
                                {
                                    string keyValue = fieldValue[dataIndex];
                                    string displayText = ExpandRow(keyValue, searchList, false);
                                    if (displayText.Length > DISPLAY_TEXT_TRIM_LENGTH) displayText = displayText.Substring(0, DISPLAY_TEXT_TRIM_LENGTH);
                                    System.Web.UI.WebControls.ListItem newListItem = new ListItem(displayText, keyValue);
                                    _ContentLookupListBox.Items.Add(newListItem);
                                    _HiddenFieldValue.Value += keyValue + "~";
                                }
                            }
                        }
                    }
       
                }
            }
        }


        #endregion

    }
}


